﻿using Castle.Core.Logging;
using Castle.Services.Transaction;
using Inovout.Memberships;
using Inovout.Repositories;
using Inovout.Runtime;
using Inovout.Security;
using System;
using System.Threading;

namespace Inovout.Services
{
    public class BaseService
    {
        protected IApplication Application
        {
            get { return ComponentRegistry.Resolve<IApplication>(); }
        }
        protected internal IExtendedLogger Logger
        {
            get;
            internal set;
        }

        private IMembershipUser membershipUser;

        protected IMembershipUser MembershipUser
        {
            get
            {
                if (membershipUser == null)
                {
                    membershipUser = ComponentRegistry.Resolve<IMembershipUserService>().FindByClaimedIdentifier(Thread.CurrentPrincipal.Identity.Name);
                }
                return membershipUser;
            }
        }

        protected IMembership Membership
        {
            get
            {
                return MembershipUser.Membership;
            }
        }
        protected ISystemUser SystemUser
        {
            get { return MembershipUser.SystemUser; }
        }

        internal BaseRepository repository;
        [Obsolete("会造成死锁，稍后改进", true)]
        protected void DoTransaction(Action action)
        {
            ITransactionManager manager = ComponentRegistry.Resolve<ITransactionManager>();
            ITransaction transaction = manager.CreateTransaction(
                TransactionMode.Requires, IsolationMode.Unspecified);

            transaction.Begin();

            bool rolledback = false;

            try
            {

                action();
                if (transaction.IsRollbackOnlySet)
                {
                    Logger.DebugFormat("Rolling back transaction {0}", transaction.GetHashCode());

                    rolledback = true;
                    transaction.Rollback();
                }
                else
                {
                    Logger.DebugFormat("Committing transaction {0}", transaction.GetHashCode());
                    transaction.Commit();
                }
            }
            catch (TransactionException ex)
            {
                if (Logger.IsFatalEnabled)
                {
                    Logger.Fatal("Fatal error during transaction processing", ex);
                }

                throw ex;
            }
            catch (Exception ex)
            {
                if (!rolledback)
                {
                    if (Logger.IsDebugEnabled)
                        Logger.DebugFormat("Rolling back transaction {0} due to exception on method", transaction.GetHashCode());

                    transaction.Rollback();
                }
                Logger.Error("WorkItem run error.", ex);
                throw ex;
            }
            finally
            {
                manager.Dispose(transaction);
            }
        }
    }
}
